const nunjucks = require('nunjucks');

function createEnv(path, opts) 
{
    var autoescape = opts.autoescape === undefined ? true : opts.autoescape;
    var noCache = opts.noCache || false;
    var watch = opts.watch || false;
    var throwOnUndefined = opts.throwOnUndefined || false;
    var env = new nunjucks.Environment(
            new nunjucks.FileSystemLoader(path, 
            {
                noCache: noCache,
                watch: watch,
            }), 
            {
                autoescape: autoescape,
                throwOnUndefined: throwOnUndefined
            });
    if (opts.filters) 
    {
        for (var f in opts.filters) 
        {
            env.addFilter(f, opts.filters[f]);
        }
    }
    return env;
}

//templating 给ctx绑定render函数
function templating(path, opts) //path表示模板所在的目录,opts表示参数对象
{
    var env = createEnv(path, opts); //env为nunjucks模板对象，有rende方法
    return async (ctx, next) => 
    {
        ctx.render = function (view, model)//给ctx对象绑定render函数
        {
            ctx.response.body = env.render( view, Object.assign({}, ctx.state || {}, model || {}) )//调用Object.assign()函数可以拷贝所有可被枚举的自有属性值到目标对象。
            /**
             * Object.assign(target, ...sources)
             * var o1 = { a: 1 };
             * var o2 = { b: 2 };
             * var o3 = { c: 3 };
             * var obj = Object.assign(o1, o2, o3);
             * console.log(obj); // { a: 1, b: 2, c: 3 }
             * console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed.  o1是target
             */
            ctx.response.type = 'text/html';
        };
        await next();
    };
}

module.exports = templating;